/**
 * HTTP请求工具类 - 封装API请求基础URL和通用方法
 * 用于统一管理API接口地址，方便后期更换端口或域名
 * 已集成storageUtil.js的token管理功能
 */

// 导入storageUtil.js中的token获取方法
const { getToken } = require('./storageUtil.js');

// API基础配置
const BASE_CONFIG = {
  // 基础URL，后期如需更换端口只需修改这里
  // 根据用户提供的接口地址，后端运行在8080端口
  // 若依框架通常需要加上上下文路径 /dev-api
  BASE_URL: 'http://localhost:8080', 
  
  // 请求超时时间（毫秒）
  TIMEOUT: 30000,
  
  // 请求头配置
  HEADER: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
}

/**
 * HTTP请求工具类
 */
class HttpUtil {
  /**
   * 构造函数
   * @param {Object} config - 自定义配置（可选）
   */
  constructor(config = {}) {
    this.config = { ...BASE_CONFIG, ...config };
  }

  /**
   * 发起HTTP请求
   * @param {Object} options - 请求配置
   * @param {string} options.url - 请求地址（相对路径，如 '/api/user/info'）
   * @param {string} options.method - 请求方法（GET/POST/PUT/DELETE）
   * @param {Object} options.data - 请求数据
   * @param {Object} options.header - 自定义请求头
   * @param {number} options.timeout - 超时时间
   * @returns {Promise} - 返回Promise对象
   */
  request(options = {}) {
    const { url, method = 'GET', data = {}, header = {}, timeout } = options;
    
    // 拼接完整URL
    const fullUrl = `${this.config.BASE_URL}${url}`;
    
    // 使用storageUtil.js提供的方法获取token
    const token = getToken();
    
    // 合并请求头，如果有token则自动添加Authorization头
    const mergedHeader = { ...this.config.HEADER, ...header };
    if (token) {
      // 若依框架通常使用 Bearer token 格式
      mergedHeader['Authorization'] = `Bearer ${token}`;
      console.log('已添加token到请求头:', token.substring(0, 10) + '...');
    } else {
      console.log('未找到token，请求可能需要认证');
    }
    
    // 设置超时时间
    const requestTimeout = timeout || this.config.TIMEOUT;
    
    return new Promise((resolve, reject) => {
      // 微信小程序请求
      wx.request({
        url: fullUrl,
        method: method,
        data: data,
        header: mergedHeader,
        timeout: requestTimeout,
        success: (res) => {
          // 添加调试信息
          console.log('HTTP请求成功:', {
            url: fullUrl,
            method: method,
            statusCode: res.statusCode,
            data: res.data,
            hasToken: !!token // 显示是否携带了token
          });
          
          // 请求成功，根据业务状态码处理
          if (res.statusCode === 200) {
          
            // 检查后端返回格式
            if (res.data && typeof res.data === 'object') {
         
              // 如果后端直接返回数据（没有包装code字段）
              if (!res.data.hasOwnProperty('code')) {
                console.log('后端返回的是直接数据格式，直接返回res.data');
                resolve(res.data);
              } 
              // 如果后端返回格式为 { code: 200, data: {}, message: 'success' }
              else if (res.data.code === 200) {
                resolve(res.data);
              } else {
                // 业务逻辑错误
                reject({
                  code: res.data.code,
                  message: res.data.message || '请求失败',
                  data: res.data
                });
              }
            } else {
              // 数据格式异常
              reject({
                code: -2,
                message: '响应数据格式异常',
                data: res
              });
            }
          } else {
            // HTTP状态码错误
            reject({
              code: res.statusCode,
              message: `HTTP错误: ${res.statusCode}`,
              data: res
            });
          }
          
          // 请求成功后，异步检查token状态（不阻塞请求流程）
          this.checkTokenAfterRequest();
        },
        fail: (err) => {
          // 添加调试信息
          console.error('HTTP请求失败:', {
            url: fullUrl,
            method: method,
            hasToken: !!token,
            error: err
          });
          
          // 网络请求失败
          reject({
            code: -1,
            message: '网络请求失败，请检查网络连接',
            data: err
          });
        }
      });
    });
  }

  /**
   * GET请求
   * @param {string} url - 请求地址
   * @param {Object} params - 请求参数
   * @param {Object} header - 自定义请求头
   * @returns {Promise}
   */
  get(url, params = {}, header = {}) {
    // 将参数拼接到URL中
    let finalUrl = url;
    if (Object.keys(params).length > 0) {
      const queryString = Object.keys(params)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
        .join('&');
      finalUrl = `${url}?${queryString}`;
    }
    
    return this.request({
      url: finalUrl,
      method: 'GET',
      header: header
    });
  }

  /**
   * POST请求
   * @param {string} url - 请求地址
   * @param {Object} data - 请求数据
   * @param {Object} header - 自定义请求头
   * @returns {Promise}
   */
  post(url, data = {}, header = {}) {
    return this.request({
      url: url,
      method: 'POST',
      data: data,
      header: header
    });
  }

  /**
   * PUT请求
   * @param {string} url - 请求地址
   * @param {Object} data - 请求数据
   * @param {Object} header - 自定义请求头
   * @returns {Promise}
   */
  put(url, data = {}, header = {}) {
    return this.request({
      url: url,
      method: 'PUT',
      data: data,
      header: header
    });
  }

  /**
   * DELETE请求
   * @param {string} url - 请求地址
   * @param {Object} params - 请求参数
   * @param {Object} header - 自定义请求头
   * @returns {Promise}
   */
  delete(url, params = {}, header = {}) {
    // 将参数拼接到URL中
    let finalUrl = url;
    if (Object.keys(params).length > 0) {
      const queryString = Object.keys(params)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
        .join('&');
      finalUrl = `${url}?${queryString}`;
    }
    
    return this.request({
      url: finalUrl,
      method: 'DELETE',
      header: header
    });
  }

  /**
   * 更新基础URL（用于动态切换环境）
   * @param {string} baseUrl - 新的基础URL
   */
  setBaseUrl(baseUrl) {
    this.config.BASE_URL = baseUrl;
  }

  /**
   * 获取当前基础URL
   * @returns {string}
   */
  getBaseUrl() {
    return this.config.BASE_URL;
  }

  /**
   * 请求成功后检查token状态
   */
  checkTokenAfterRequest() {
    try {
      // 异步检查token，不阻塞主流程
      setTimeout(() => {
        const { tokenService } = require('./tokenService.js');
        if (tokenService) {
          tokenService.manualCheckToken().catch(err => {
            console.log('异步token检查失败:', err);
          });
        }
      }, 100);
    } catch (error) {
      console.log('Token检查失败:', error);
    }
  }
}

// 创建默认实例
const http = new HttpUtil();

// 导出类和默认实例
module.exports = { HttpUtil, http };